home *** CD-ROM | disk | FTP | other *** search
/ Mac100% 1998 November / MAC100-1998-11.ISO.7z / MAC100-1998-11.ISO / スクリーンセーバーファクトリー / DarkSide of the Mac 5.0.2 / SampleFaders / Fader.c next >
C/C++ Source or Header  |  1997-02-11  |  13KB  |  509 lines

  1. /*
  2.     DarkSide - a 7.0 dependant, system clean expandable screen saver.
  3.     
  4.     copyright ゥハ1990-1997 by Tom Dowdy
  5.     All rights reserved.
  6.     
  7.     This fader shell serves to dispatch requests from the main DarkSide code
  8.     into the appropriate entry points.
  9. */
  10. #include <StdArg.h>
  11. #include <Memory.h>
  12. #include <Packages.h>
  13. #include <Errors.h>
  14.  
  15. #include "Fader.h"
  16. #ifdef THINK_C
  17.     #include <SetupA4.h>
  18. #endif
  19.  
  20. #ifdef powerc
  21.  
  22. RoutineDescriptor preflightFaderUPP = BUILD_ROUTINE_DESCRIPTOR(uppPreflightFaderProcInfo,PreflightFader);
  23. RoutineDescriptor initializeFaderUPP = BUILD_ROUTINE_DESCRIPTOR(uppInitializeFaderProcInfo,InitializeFader);
  24. RoutineDescriptor idleFaderUPP = BUILD_ROUTINE_DESCRIPTOR(uppIdleFaderProcInfo,IdleFader);
  25. RoutineDescriptor disposeFaderUPP = BUILD_ROUTINE_DESCRIPTOR(uppDisposeFaderProcInfo,DisposeFader);
  26. RoutineDescriptor updateFaderUPP = BUILD_ROUTINE_DESCRIPTOR(uppUpdateFaderProcInfo,UpdateFader);
  27. RoutineDescriptor hitFaderUPP = BUILD_ROUTINE_DESCRIPTOR(uppHitFaderProcInfo,HitFader);
  28.    
  29. #endif
  30.     
  31. /* ------------------------------------------------------------------------    */
  32. /* GLOBAL HANDLING ROUTINES */
  33. /* ------------------------------------------------------------------------    */
  34. void    DebugLongInt(long aLong);
  35.  
  36. #ifndef THINK_C
  37.     OSErr    CreateA5World(Ptr * a5World);
  38.     void    DisposeA5World(Ptr a5World, Ptr appA5);
  39. #endif
  40.  
  41. /* ------------------------------------------------------------------------    */
  42. #ifndef powerc
  43.  
  44. #ifdef THINK_C
  45.     OSErr    main(long selector, Ptr *a5World, MachineInfoPtr machineInfo, ...)
  46. #else
  47.     OSErr    FaderEntry(long selector, Ptr *a5World, MachineInfoPtr machineInfo, ...)
  48. #endif
  49. {
  50.     OSErr    anErr = noErr;
  51.     va_list    nextArg;
  52.         
  53.     #ifdef THINK_C
  54.         // Set up A4 so that we can use global variables...
  55.         RememberA0();
  56.         SetUpA4();
  57.     #endif
  58.     
  59.     // start stripping optional arguments
  60.     va_start(nextArg, machineInfo);
  61.     
  62.     switch(selector)
  63.         {
  64.         case preflightFader:
  65.             {
  66.             long    *minTicks, *maxTicks;
  67.             
  68.             minTicks = va_arg(nextArg, long*);
  69.             maxTicks = va_arg(nextArg, long*);
  70.             
  71.             #ifndef THINK_C
  72.                 #ifndef powerc
  73.                     anErr = CreateA5World(a5World);
  74.                 #endif
  75.             #endif
  76.             
  77.             if (anErr == noErr)
  78.                 {
  79.                 #ifndef THINK_C
  80.                     #ifndef powerc
  81.                         (void) SetA5((long) *a5World);
  82.                     #endif
  83.                 #endif
  84.                 
  85.                 BlockMove(machineInfo->applicationQD, &qd, sizeof(qd));
  86.                 anErr = PreflightFader(machineInfo, minTicks, maxTicks);
  87.                 BlockMove(&qd, machineInfo->applicationQD, sizeof(qd));
  88.                 }
  89.             }
  90.             break;
  91.             
  92.         case initializeFader:
  93.             #ifndef THINK_C
  94.                 (void) SetA5((long) *a5World);
  95.             #endif
  96.  
  97.             BlockMove(machineInfo->applicationQD, &qd, sizeof(qd));
  98.             anErr = InitializeFader(machineInfo);
  99.             BlockMove(&qd, machineInfo->applicationQD, sizeof(qd));
  100.             break;
  101.             
  102.         case idleFader:
  103.             #ifndef THINK_C
  104.                 (void) SetA5((long) *a5World);
  105.             #endif
  106.  
  107.             anErr = IdleFader(machineInfo);
  108.             break;
  109.             
  110.         case disposeFader:
  111.             {
  112.             
  113.             #ifndef THINK_C
  114.                 (void) SetA5((long) *a5World);
  115.             #endif
  116.  
  117.             BlockMove(machineInfo->applicationQD, &qd, sizeof(qd));
  118.             anErr = DisposeFader(machineInfo);
  119.             BlockMove(&qd, machineInfo->applicationQD, sizeof(qd));
  120.  
  121.             #ifndef THINK_C
  122.                 DisposeA5World(*a5World, (Ptr)machineInfo->applicationA5);
  123.             #endif
  124.             
  125.             }
  126.             break;
  127.  
  128.         case updateFader:
  129.             #ifndef THINK_C
  130.                 (void) SetA5((long) *a5World);
  131.             #endif
  132.             anErr = UpdateFader(machineInfo);
  133.             break;
  134.             
  135.         case hitFader:
  136.             {
  137.             DialogPtr    dPtr;
  138.             long        itemHit;
  139.             long        itemOffset;
  140.                         
  141.             dPtr         = va_arg(nextArg, DialogPtr);
  142.             itemHit     = va_arg(nextArg, long);
  143.             itemOffset     = va_arg(nextArg, long);
  144.  
  145.             anErr = HitFader(machineInfo, dPtr, itemHit, itemOffset);            
  146.             }
  147.             
  148.             break;
  149.             
  150.         default:
  151.             // function not found error
  152.             anErr = fnfErr;
  153.             break;
  154.         }
  155.         
  156.     va_end(nextArg);
  157.     
  158.     #ifdef THINK_C
  159.         RestoreA4();
  160.     #else
  161.         (void) SetA5((long) machineInfo->applicationA5);
  162.     #endif
  163.     
  164.     return(anErr);    
  165.     
  166. } // FaderEntry
  167.  
  168. #endif
  169.  
  170. /* ------------------------------------------------------------------------    */
  171. /* DEBUGGING ROUTINES                             */
  172. /* ------------------------------------------------------------------------    */
  173. void DebugLongInt(long theLong)
  174. {
  175.     Str255 theString;
  176.     
  177.     NumToString(theLong, theString);
  178.     DebugStr(theString);
  179.     
  180. } // DebugLongInt
  181.  
  182.  
  183. /* ------------------------------------------------------------------------    */
  184. /* FADER UTILS                                                                 */
  185. /* ------------------------------------------------------------------------    */
  186.  
  187. Handle    BestNewHandle(Size    theSize)
  188. /*
  189.     Tries to get the handle from the temp memory first, if that fails, it goes
  190.     to the application.
  191. */
  192. {
  193.     Handle theHandle;
  194.     OSErr    anErr;
  195.     
  196.     theHandle = TempNewHandle(theSize, &anErr);
  197.     if (theHandle == nil)
  198.         theHandle = NewHandle(theSize);
  199.         
  200.     return(theHandle);
  201.     
  202. } // BestNewHandle
  203.  
  204. /* ------------------------------------------------------------------------    */
  205.  
  206. RgnHandle    BestNewRgn()
  207. /*
  208.     Tries to get a rgn handle from the temp memory first, if that fails, it goes
  209.     to the application.  Needs enough room in the app heap to create the region
  210.     in the first place.
  211. */
  212. {
  213.     RgnHandle     theRgn;
  214.     OSErr        anErr;
  215.     
  216.     // make a region
  217.     theRgn = NewRgn();
  218.     if (theRgn != nil)
  219.         {
  220.         RgnHandle    theHandle;
  221.         short        regionSize;
  222.         
  223.         // try to make something the same size in the temp memory
  224.         regionSize = GetHandleSize((Handle) theRgn);
  225.         theHandle = (RgnHandle) TempNewHandle(regionSize, &anErr);
  226.         if (anErr == noErr)
  227.             {
  228.             // if we get it, use that one for our region
  229.             BlockMove(*theRgn, *theHandle, regionSize);
  230.             DisposeRgn(theRgn);
  231.             theRgn = theHandle;
  232.             }
  233.         }
  234.         
  235.     return(theRgn);
  236.     
  237. } // BestNewRgn
  238.  
  239.  
  240.  
  241. /* ------------------------------------------------------------------------    */
  242.  
  243. short    Rnd(long max)
  244. /*
  245.     Returns a number > 0 and < max
  246. */
  247. {
  248.     unsigned long value;
  249.  
  250.     value = (unsigned short)max * (unsigned short)Random();
  251.     value >>= 16;
  252.     return(value);
  253.     
  254. } // Rnd
  255.  
  256. /* ------------------------------------------------------------------------    */
  257. void PlaceRectOnScreen(
  258.     MachineInfoPtr machineInfo,    // give info about the machine here
  259.     short width,                // width of rect, can be 0
  260.     short height,                // height of rect, can be 0
  261.     Rect * placedRect,            // Placed rect is returned here
  262.     Rect * margins,                // margins around screen, can be nil
  263.     short * whichScreen)        // screen index returned here, can be nil
  264. {
  265.     Rect        screenRect;
  266.     short        pickScreen;
  267.  
  268.     // pick a random screen    
  269.     pickScreen = Rnd(machineInfo->numScreens);
  270.     screenRect = machineInfo->theScreens[pickScreen].bounds;
  271.     if (whichScreen != nil)
  272.         *whichScreen = pickScreen;
  273.         
  274.     if (margins != nil)
  275.         {
  276.         screenRect.top += margins->top;
  277.         screenRect.left += margins->left;
  278.         screenRect.bottom -= margins->bottom;
  279.         screenRect.right -= margins->right;
  280.         }
  281.         
  282.     screenRect.right -= width;
  283.     screenRect.bottom -= height;
  284.     
  285.     if (placedRect != nil)
  286.         {
  287.         placedRect->top = screenRect.top + Rnd(screenRect.bottom - screenRect.top);
  288.         placedRect->left = screenRect.left + Rnd(screenRect.right - screenRect.left);
  289.         placedRect->bottom = placedRect->top + height;
  290.         placedRect->right = placedRect->left + width;
  291.         }
  292.         
  293. } // PlaceRectOnScreen
  294.  
  295. #ifndef THINK_C
  296. #ifndef powerc
  297. /* ------------------------------------------------------------------------    */
  298. /* FUN A5 STUFF - See Tech note 256 for details                             */
  299. /* ------------------------------------------------------------------------    */
  300. long A5Size(); 
  301. void A5Init(Ptr theA5);
  302.  
  303. OSErr    CreateA5World(Ptr * a5World)
  304. {
  305.     OSErr    anErr;
  306.     Ptr        theWorld = nil;
  307.     Handle    worldHandle;
  308.     
  309.     worldHandle = BestNewHandle(A5Size());
  310.     anErr = MemError();
  311.     if (anErr == noErr)
  312.         {
  313.         HLockHi(worldHandle);
  314.         theWorld = *worldHandle;
  315.         
  316.         theWorld += + A5Size() - 32;
  317.         A5Init(theWorld);
  318.         
  319.         // very important if anyone wants to call SwapMMUMode
  320.         theWorld = StripAddress(theWorld);
  321.         }
  322.     *a5World = theWorld;
  323.     
  324.     return(anErr);
  325.     
  326. } // CreateA5World
  327.  
  328. /* ------------------------------------------------------------------------    */
  329. void    DisposeA5World(Ptr a5World, Ptr appA5)
  330. {
  331.     
  332.     (void) SetA5((long) appA5);
  333.     
  334.     {
  335.     Handle    theHandle = RecoverHandle(a5World - A5Size() + 32);
  336.     
  337.     DisposHandle(theHandle);
  338.     }
  339.     
  340. } // DisposeA5World
  341. #endif
  342. #endif
  343.  
  344. #ifdef THINK_C
  345. /* ------------------------------------------------------------------------    */
  346. /* CALLBACK WRAPPERS
  347. /* ------------------------------------------------------------------------    */
  348. OSErr    WritePreferencesHandle(MachineInfoPtr machineInfo, Handle h, ResType theType)
  349. {
  350.     OSErr    anErr;
  351.     long    curA5;
  352.     long    loader;
  353.     
  354.     curA5 = SetA5((long) machineInfo->applicationA5);
  355.     loader = (long) machineInfo->callbackLoader;
  356.     asm {
  357.         move.l theType, -(SP)
  358.         move.l h, -(SP)
  359.         move.l loader, a0
  360.         moveq #0, d0
  361.         pea @returnAddress
  362.         move.l #0x08000004, -(SP)
  363.         jmp (a0)
  364.     @returnAddress:
  365.         move.w d0, anErr
  366.         add #8, SP
  367.     }
  368.     SetA5(curA5);
  369.     return(anErr);
  370.     
  371. } // WritePreferencesHandle
  372.  
  373. /* ------------------------------------------------------------------------    */
  374. OSErr    ReadPreferencesHandle(MachineInfoPtr machineInfo, Handle *h, ResType theType)
  375. {
  376.     OSErr    anErr;
  377.     long    curA5;
  378.     long    loader;
  379.     
  380.     curA5 = SetA5((long) machineInfo->applicationA5);
  381.     loader = (long) machineInfo->callbackLoader;
  382.     asm {
  383.         move.l theType, -(SP)
  384.         move.l h, -(SP)
  385.         move.l loader, a0
  386.         moveq #0, d0
  387.         pea @returnAddress
  388.         move.l #0x08000008, -(SP)
  389.         jmp (a0)
  390.     @returnAddress:
  391.         move.w d0, anErr
  392.         add #8, SP
  393.     }
  394.     SetA5(curA5);
  395.     return(anErr);
  396.     
  397. } // ReadPreferencesHandle
  398.  
  399. /* ------------------------------------------------------------------------    */
  400. // While translating this code from MPW C to THINK C I found out that the calling conventions
  401. // of these languages seem to be different. If we have a short and a Boolean as below, THINK C
  402. // pushes them both into a longword, while MPW C uses a longword for each. Very confusing!
  403.  
  404. OSErr    PlayResourceSnd(MachineInfoPtr machineInfo, short theID, Boolean async)
  405. {
  406.     OSErr    anErr;
  407.     long    loader;
  408.     
  409.     loader = (long) machineInfo->callbackLoader;
  410.     asm {
  411.         moveq #0, d0
  412.         move.b async, d0                                // convert async to longword
  413.         move.l d0, -(SP)                                // and push it
  414.  
  415.         moveq #0, d0                                    // convert theID to longword
  416.         move.w theID, d0                                // and push it
  417.         move.l d0, -(SP)
  418.         
  419.         move.l loader, a0
  420.         moveq #0, d0
  421.         pea @returnAddress                                // push return address
  422.         move.l #0x0800000C, -(SP)                        // push selector code
  423.         jmp (a0)                                        // jump to callback loader
  424.     @returnAddress:
  425.         move.w d0, anErr                                // save result code                                
  426.         add #8, SP                                        // adjust stack
  427.     }
  428.     return anErr;
  429.     
  430. } // PlayResourceSnd
  431.  
  432. #else
  433.  
  434. /* ------------------------------------------------------------------------    */
  435. /* CALLBACK DEFINES
  436. /* ------------------------------------------------------------------------    */
  437. #ifndef powerc
  438.     #pragma parameter __D0 DoWritePreferencesHandle(__A0)
  439.     OSErr DoWritePreferencesHandle(Ptr M, Handle h, ResType theType) = 
  440.         { 0x7000, 0x487B, 0x000A, 0x2F3C, 0x0800, 0x0004, 0x4ED0};
  441.     #pragma parameter __D0 DoReadPreferencesHandle(__A0)
  442.     OSErr DoReadPreferencesHandle(Ptr M, Handle *h, ResType theType) = 
  443.         { 0x7000, 0x487B, 0x000A, 0x2F3C, 0x0800, 0x0008, 0x4ED0};
  444.     #pragma parameter __D0 DoPlayResourceSnd(__A0)
  445.     OSErr DoPlayResourceSnd(Ptr M, short theID, Boolean async) = 
  446.         { 0x7000, 0x487B, 0x000A, 0x2F3C, 0x0800, 0x000C, 0x4ED0};
  447. #endif
  448.  
  449. /* ------------------------------------------------------------------------    */
  450. /* CALLBACK WRAPERS
  451. /* ------------------------------------------------------------------------    */
  452. OSErr    WritePreferencesHandle(MachineInfoPtr machineInfo, Handle h, ResType theType)
  453. {
  454.     OSErr    anErr;
  455.  
  456.     #ifdef powerc
  457.         anErr = CallUniversalProc((UniversalProcPtr) machineInfo->callbackLoader, uppCallbackInfo, callbackWritePreferencesHandle, h, theType);
  458.     #else
  459.         long    curA5;
  460.         
  461.         curA5 = SetA5((long)machineInfo->applicationA5);
  462.         anErr = DoWritePreferencesHandle(machineInfo->callbackLoader, h, theType);
  463.         SetA5(curA5);
  464.     #endif
  465.     
  466.     return(anErr);
  467.     
  468. } // WritePreferencesHandle
  469.  
  470. /* ------------------------------------------------------------------------    */
  471. OSErr    ReadPreferencesHandle(MachineInfoPtr machineInfo, Handle *h, ResType theType)
  472. {
  473.     OSErr    anErr;
  474.  
  475.     #ifdef powerc
  476.         anErr = CallUniversalProc((UniversalProcPtr) machineInfo->callbackLoader, uppCallbackInfo, callbackReadPreferencesHandle, h, theType);
  477.     #else
  478.         long    curA5;
  479.         
  480.         curA5 = SetA5((long)machineInfo->applicationA5);
  481.         anErr = DoReadPreferencesHandle(machineInfo->callbackLoader, h, theType);
  482.         SetA5(curA5);
  483.     #endif
  484.     
  485.     return(anErr);
  486.     
  487. } // ReadPreferencesHandle
  488.  
  489. /* ------------------------------------------------------------------------    */
  490. OSErr    PlayResourceSnd(MachineInfoPtr machineInfo, short theID, Boolean async)
  491. {
  492.     OSErr    anErr;
  493.  
  494.     #ifdef powerc
  495.         anErr = CallUniversalProc((UniversalProcPtr) machineInfo->callbackLoader, uppCallbackInfo, callbackPlayResourceSnd, (long)theID, (long)async);
  496.     #else
  497.         long    curA5;
  498.         
  499.         curA5 = SetA5((long)machineInfo->applicationA5);
  500.         anErr = DoPlayResourceSnd(machineInfo->callbackLoader, theID, async);
  501.         SetA5(curA5);
  502.     #endif
  503.     
  504.     return(anErr);
  505.     
  506. } // PlayResourceSnd
  507.  
  508. #endif
  509.